using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Threading;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.Diagnostics;
using Microsoft.WindowsAzure.ServiceRuntime;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Table;
using Validator.Entities;
using System.Configuration;

namespace Validator
{
    public class WorkerRole : RoleEntryPoint
    {
#error STORAGE_CONNECTION_STRING must be defined in app.config
        static private string STORAGE_CONNECTION_STRING = ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString;

        private CloudTable rawdataTable;

        private void ConfigureDiagnostics(CloudStorageAccount storageAccount)
        {
            string wadConnectionString = "Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString";

            LocalResource traceResource = RoleEnvironment.GetLocalResource("DiagnosticStore");
            DiagnosticMonitorConfiguration config = DiagnosticMonitor.GetDefaultInitialConfiguration();
            config.ConfigurationChangePollInterval = TimeSpan.FromMinutes(1d);
            config.Directories.DataSources.Add(new DirectoryConfiguration { Path = traceResource.RootPath, Container = "wad-trace-container", DirectoryQuotaInMB = 100 });
            config.Logs.BufferQuotaInMB = 500;
            config.Logs.ScheduledTransferLogLevelFilter = LogLevel.Verbose; // Transfer verbose, critical, etc. logs
            config.Logs.ScheduledTransferPeriod = TimeSpan.FromMinutes(1d); // Transfer logs to storage every minute

            DiagnosticMonitor.Start(wadConnectionString, config); // Start up the diagnostic manager with the given configuration
        }


        public override void Run()
        {
            // This is a sample worker implementation. Replace with your logic.
            Trace.TraceInformation("Validator entry point called", "Information");

            while (true)
            {
                try
                {
                    Trace.WriteLine("Searching table for new data...", "Information");
                    TableQuery<MomentEntity> query = new TableQuery<MomentEntity>();

                    Dictionary<string, List<MomentEntity>> datasets = new Dictionary<string, List<MomentEntity>>();

                    foreach(MomentEntity entity in rawdataTable.ExecuteQuery(query))
                    {
                        if (datasets.Keys.Contains(entity.VIN))
                            datasets[entity.PartitionKey].Add(entity);
                        else
                        {
                            datasets.Add(entity.VIN, new List<MomentEntity>());
                            datasets[entity.PartitionKey].Add(entity);
                        }
                    }

                    this.ProcessDatasets(datasets);
                }
                catch (Exception ex)
                {
                    Trace.TraceError("An error occurred while attempting to process datasets. {0}", ex.Message);
                }
            }
        }

        private void ProcessDatasets(Dictionary<string, List<MomentEntity>> datasets)
        {
            foreach (string group in datasets.Keys)
            {
                List<MomentEntity> rawdata = datasets[group];
                
                Manager validator = new Manager();
                foreach (MomentEntity moment in rawdata)
                    validator.Current = moment;
            }
        }

        public override bool OnStart()
        {
            // Set the maximum number of concurrent connections 
            ServicePointManager.DefaultConnectionLimit = 12;

            // For information on handling configuration changes
            // see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357.

            var storageAccount = CloudStorageAccount.Parse(STORAGE_CONNECTION_STRING);

            this.ConfigureDiagnostics(storageAccount);

            Trace.WriteLine("Initializing Storage Accounts for Analyzer");

            var blobClient = storageAccount.CreateCloudBlobClient();
            var tableClient = storageAccount.CreateCloudTableClient();
            var queueClient = storageAccount.CreateCloudQueueClient();

            rawdataTable = tableClient.GetTableReference("moments");
            rawdataTable.CreateIfNotExists();

            return base.OnStart();
        }
    }
}
